package com.thermal.thermal_inspection.service.impl;

import com.thermal.thermal_inspection.entity.Inspection;
import com.thermal.thermal_inspection.entity.InspectionData;
import com.thermal.thermal_inspection.entity.Map;
import com.thermal.thermal_inspection.mapper.*;
import com.thermal.thermal_inspection.entity.InspectionWork;
import com.thermal.thermal_inspection.mapper.InspectionDataMapper;
import com.thermal.thermal_inspection.mapper.InspectionDetailMapper;
import com.thermal.thermal_inspection.mapper.InspectionMapper;
import com.thermal.thermal_inspection.mapper.InspectionWorkMapper;
import com.thermal.thermal_inspection.entity.*;
import com.thermal.thermal_inspection.service.CacheService;
import com.thermal.thermal_inspection.service.InspectionService;
import com.thermal.thermal_inspection.vo.*;
import com.thermal.thermal_inspection.vo.MapDetailVO;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class InspectionServiceImpl implements InspectionService {
    private static final Logger logger = Logger.getLogger(InspectionServiceImpl.class);

    // 虚拟环境中的 python 可执行文件路径
    String pythonInterpreter = "D:\\Python3.12.6\\python.exe";

    String basePath = "D:\\Tool\\nginx\\html";
    String scriptPath = "D:\\火电巡检系统开发\\cheat_detection\\main.py";

    //其他相关路径分别在741-743，784，797（提交数据接口），调用python在853行，取出保存图片相关路径在938,940行


    @Autowired
    CacheService cacheService;

    //缓存过期时间单位
    static final int timeOut = 10;
    static final TimeUnit timeUnit = TimeUnit.MINUTES;

    @Autowired
    InspectionMapper inspectionMapper;
    @Autowired
    InspectionDataMapper inspectionDataMapper;
    @Autowired
    InspectionWorkMapper inspectionWorkMapper;
    @Autowired
    InspectionDetailMapper inspectionDetailMapper;
    @Autowired
    private MapDetailMapper mapDetailMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    MapMapper mapMapper;
    @Autowired
    ClassMapper classMapper;
    @Autowired
    RealNameMapper realNameMapper;
    @Autowired
    InspectionGroupMapper inspectionGroupMapper;

    /**
     *判断是否存在巡检任务名
     */
    @Override
    public boolean existInspectionName(String inspectionName) {
        return inspectionMapper.getInspectionByName(inspectionName) != null;
    }

    /**
     * 新增巡检任务
     */
    @Override
    public int addInspection(String inspectionName, int inspectionUserId, int inspectionClassId, int inspectionMapId){
        Timestamp inspectionDate = new Timestamp(System.currentTimeMillis());
        return inspectionMapper.addInspection(inspectionName, inspectionDate, inspectionUserId, inspectionClassId, inspectionMapId);
    }

    /**
     * 通过巡检任务名获得巡检任务
     */
    @Override
    public Inspection getInspectionByName(String inspectionName){
        return inspectionMapper.getInspectionByName(inspectionName);
    }

    /**
     * 新增巡检任务详情
     */
    public int addInspectionData(int inspectionId, int inspectionGroupId, int mapDetailId, String inspectionDataDesc, String inspectionDataName){
        return inspectionDataMapper.addInspectionData(inspectionId, inspectionGroupId, mapDetailId, inspectionDataDesc, inspectionDataName);
    }
    /**
     * 判断分配的巡检任务名是否存在
     */
    @Override
    public boolean existInspectionWorkName(String inspectionWorkName){
        return inspectionWorkMapper.getInspectionWorkByName(inspectionWorkName) != null;
    }

    /**
     * 查看分配的模板任务是否存在
     */
    @Override
    public boolean existInspection(int inspectionId){
        return inspectionMapper.getInspectionById(inspectionId) != null;
    }

    /**
     * 新增inspection_work表
     */
    @Override
    public int addInspectionWork(Timestamp inspectionStartTime, int inspectionLimitTime, String inspectionWorkName,
                                 int inspectionId, int inspectionWorkNumber, int inspectionWorkStatus){
        return inspectionWorkMapper.addInspectionWork(inspectionStartTime, inspectionLimitTime, inspectionWorkName,
                inspectionId, inspectionWorkNumber, inspectionWorkStatus);
    }

    /**
     * 获取所有任务模版
     * @return List<Inspection>
     */
    @Override
    public List<Inspection> getAllInspectionTemplates() {
        return inspectionMapper.getAllInspectionTemplates();
    }

    /**
     * 获取所有任务模版详情
     * @return List<InspectionDataVO>
     */
    @Override
    public List<InspectionDataVO> getAllInspectionDataVOs(int inspectionId,int inspectionMapId) {
        List<InspectionData> inspectionDatas = inspectionDataMapper.getInspectionDataByInspectionId(inspectionId);
        System.out.println(inspectionDatas);
        List<MapDetailVO> mapDetailVOS = mapDetailMapper.getAllMapDetail(inspectionMapId);
        System.out.println(mapDetailVOS);
        //把这两个根据mapDetailId结合起来
        List<InspectionDataVO> inspectionDataVOS = new ArrayList<>();
        for (InspectionData inspectionData : inspectionDatas){
            for (MapDetailVO mapDetailVO : mapDetailVOS){
                if (inspectionData.getMapDetailId() == mapDetailVO.getMapDetailId()){
                    InspectionDataVO inspectionDataVO = new InspectionDataVO();
                    inspectionDataVO.setInspectionData(inspectionData);
                    inspectionDataVO.setMapDetailVO(mapDetailVO);
                    inspectionDataVOS.add(inspectionDataVO);
                    //删除已结合的点位
                    mapDetailVOS.remove(mapDetailVO);
                    break;
                }
            }
        }
        if (inspectionDataVOS.size() != inspectionDatas.size()){
            return null;
        }
            return inspectionDataVOS;
    }

    /**
     * 通过name获取inspection_work
     */
    @Override
    public InspectionWork getInspectionWorkByName(String inspectionWorkName){
        return inspectionWorkMapper.getInspectionWorkByName(inspectionWorkName);
    }

    /**
     * 插入inspection_detail表
     */
    @Override
    public int addInspectionDetail(int inspectionWorkId, int inspectionDataId, int inspectionDetailClass,
                                   int inspectionDetailUser, int inspectionDetailStatus, String inspectionDetailNote){
        return inspectionDetailMapper.addInspectionDetail(inspectionWorkId, inspectionDataId, inspectionDetailClass,
                inspectionDetailUser, inspectionDetailStatus, inspectionDetailNote);
    }

    /**
     * 查看分配的巡检任务
     */
    @Override
    public List<InspectionVO> getInspection(int userId){
        List<InspectionVO> inspectionVOList = new ArrayList<>();
        int role = userMapper.getRoleById(userId);
        if(role == 3) {
            //如果查询的人是编辑者，那么他只可以看到自己的巡检任务且若此时巡检任务的状态是未开始，则他们无法点击查看详情
            inspectionVOList.addAll(getInspectionVOById(userId));
            return inspectionVOList;
        }
        else {
            //若查询的人是根用户和管理员，那么他们可以看到全部的巡检任务并无论此时巡检任务的状态是什么他们都可以查看
            List<Integer> inspectionWorkIdList = inspectionWorkMapper.getInspectionWorkId();
            for(int inspectionWorkId:inspectionWorkIdList) {
                InspectionWork inspectionWork = inspectionWorkMapper.getInspectionWorkById(inspectionWorkId);
                Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
                Map map = mapMapper.getMap(inspection.getInspectionMapId());
                InspectionVO inspectionVO = new InspectionVO(map, inspection, inspectionWork);
                inspectionVOList.add(inspectionVO);
            }

            LinkedHashSet<InspectionVO> hashSet = new LinkedHashSet<>(inspectionVOList);
            List<InspectionVO> list = new ArrayList<>(hashSet);
            return list;
        }
    }

    //编辑者通过userId查询对应的inspectionVO
    List<InspectionVO> getInspectionVOById(int userId){
        //先通过userId获取所有InspectionWork,然后每个inspectionWork都可以获取到对应的inspection和map
        List<InspectionVO> inspectionVOList = new ArrayList<>();
        List<Integer> inspectionWorkIdList = inspectionDetailMapper.getInspectionWorkIdByUserId(userId);
        List<Integer> startInspectionWorkIdList = new ArrayList<>();
        //排除掉状态为4未开始的任务
        for(int inspectionWorkId:inspectionWorkIdList){
            if(inspectionWorkMapper.getInspectionWorkById(inspectionWorkId).getInspectionWorkStatus() != 4)
                startInspectionWorkIdList.add(inspectionWorkId);
        }
        for(int inspectionWorkId:startInspectionWorkIdList) {
            InspectionWork inspectionWork = inspectionWorkMapper.getInspectionWorkById(inspectionWorkId);
            //inspectionWork中的inspectionWorkNumber和inspectionWorkFinish需要根据特定用户进行查询
            int userInspectionWorkNumber = inspectionDetailMapper.getUserInspectionWorkNumber(userId, inspectionWork.getInspectionWorkId());
            int userInspectionWorkFinish = inspectionDetailMapper.getUserInspectionWorkFinish(userId, inspectionWork.getInspectionWorkId());
            inspectionWork.setInspectionWorkNumber(userInspectionWorkNumber);
            inspectionWork.setInspectionWorkFinish(userInspectionWorkFinish);
            Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
            Map map = mapMapper.getMap(inspection.getInspectionMapId());
            InspectionVO inspectionVO = new InspectionVO(map, inspection, inspectionWork);
            inspectionVOList.add(inspectionVO);
        }
        return inspectionVOList;
    }

    /**
     * 查看分配的巡检任务详情
     */
    @Override
    public List<InspectionDetailVO> getInspectionDetail(int inspectionWorkId, int userId){
        List<InspectionDetailVO> inspectionDetailVOList = new ArrayList<>();
        int role = userMapper.getRoleById(userId);
        if(role == 3) {
            //如果此时查看的用户是编辑者，那么他们只能查看自己的巡检点位任务且需要经过nfc签到才能解锁对应巡检点位任务，然后他才能填数据并保存。
            InspectionWork inspectionWork = inspectionWorkMapper.getInspectionWorkById(inspectionWorkId);
            List<InspectionData> inspectionDataList = inspectionDataMapper.getInspectionDataListById(inspectionWork.getInspectionId());
            Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
            List<MapDetailVO> mapDetailList = mapDetailMapper.getAllMapDetail(inspection.getInspectionMapId());
            List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByWorkIdAndUser(inspectionWorkId, userId);
            return getInspectionDetailVOList(inspectionDataList, inspectionDetailList, mapDetailList);
        }
        else {
            //如果此时查看的用户是管理员和根用户，那么他们的可以查看此巡检任务的所有巡检点位任务且无需NFC签到就可以查看巡检点位任务的详情
            InspectionWork inspectionWork = inspectionWorkMapper.getInspectionWorkById(inspectionWorkId);
            List<InspectionData> inspectionDataList = inspectionDataMapper.getInspectionDataListById(inspectionWork.getInspectionId());
            Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
            List<MapDetailVO> mapDetailList = mapDetailMapper.getAllMapDetail(inspection.getInspectionMapId());
            List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByWorkId(inspectionWorkId);
            return getInspectionDetailVOList(inspectionDataList, inspectionDetailList, mapDetailList);
        }
    }

    //通过inspectionDataList,inspectionDetailList,mapDetailList三张表查询出inspectionDetailVOList
    private List<InspectionDetailVO> getInspectionDetailVOList(List<InspectionData> inspectionDataList, List<InspectionDetail> inspectionDetailList,
                                      List<MapDetailVO> mapDetailList){
        //inspectionDataList:
        //inspectionDetailList:
        //mapDetailList:
        List<InspectionDetailVO> inspectionDetailVOList = new ArrayList<>();


        for(InspectionData inspectionData:inspectionDataList){
            for(InspectionDetail inspectionDetail:inspectionDetailList){
                //inspectionData和inspectionDetail的inspection_data_id一样
                if(inspectionData.getInspectionDataId() == inspectionDetail.getInspectionDataId()){
                    for(MapDetailVO mapDetailVO:mapDetailList){
                        //inspectionData和mapDetail的map_detail_id一样
                        if(inspectionData.getMapDetailId() == mapDetailVO.getMapDetailId()){
                            //插入到inspectionDetailVOList里面
                            //inspectionData对象属性
                            InspectionDetailVO inspectionDetailVO = new InspectionDetailVO();
                            inspectionDetailVO.setInspectionData(inspectionData);

                            //inspectionDetail属性
                            inspectionDetailVO.setInspectionDetailId(inspectionDetail.getInspectionDetailId());
                            inspectionDetailVO.setInspectionDataValue(inspectionDetail.getInspectionDataValue());
                            inspectionDetailVO.setInspectionDetailCheatmsg(inspectionDetail.getInspectionDetailCheatmsg());
                            //通过班级id获取班级名字
                            String inspectionDetailClass = classMapper.getNameById(inspectionDetail.getInspectionDetailClass());
                            inspectionDetailVO.setInspectionDetailClass(inspectionDetailClass);
                            inspectionDetailVO.setInspectionDetailId(inspectionDetail.getInspectionDetailId());
                            inspectionDetailVO.setInspectionDetailImg(inspectionDetail.getInspectionDetailImg());
                            inspectionDetailVO.setInspectionDetailIscheat(inspectionDetail.getInspectionDetailIscheat());
                            inspectionDetailVO.setInspectionDetailScore(inspectionDetail.getInspectionDetailScore());
                            inspectionDetailVO.setInspectionDetailStatus(inspectionDetail.getInspectionDetailStatus());
                            //通过用户id获取用户名字
                            String inspectionDetailUser = realNameMapper.getRealNameByUserId(inspectionDetail.getInspectionDetailUser()).getRealName();
                            //String inspectionDetailUser = userMapper.getUserByUserId(inspectionDetail.getInspectionDetailUser()).getUsername();
                            inspectionDetailVO.setInspectionDetailUser(inspectionDetailUser);
                            inspectionDetailVO.setInspectionEndTime(inspectionDetail.getInspectionEndTime());
                            inspectionDetailVO.setInspectionWorkId(inspectionDetail.getInspectionWorkId());
                            inspectionDetailVO.setInspectionDetailNote(inspectionDetail.getInspectionDetailNote());

                            //mapDetail属性
                            inspectionDetailVO.setMapId(mapDetailVO.getMapId());
                            inspectionDetailVO.setMapLatitude(mapDetailVO.getMapLatitude());
                            inspectionDetailVO.setMapLongitude(mapDetailVO.getMapLongitude());
                            inspectionDetailVO.setUnitName(mapDetailVO.getUnitName());
                            inspectionDetailVO.setMapNfcMsg(mapDetailVO.getMapNfcMsg());
                            inspectionDetailVO.setMapDetailId(mapDetailVO.getMapDetailId());
                            inspectionDetailVO.setMapDetailDesc(mapDetailVO.getMapDetailDesc());

                            //最后添加到inspectionDetailVOList里面
                            inspectionDetailVOList.add(inspectionDetailVO);
                        }
                    }
                }
            }
        }
        LinkedHashSet<InspectionDetailVO> hashSet = new LinkedHashSet<>(inspectionDetailVOList);
        List<InspectionDetailVO> list = new ArrayList<>(hashSet);
        return list;
    }

    /**
     * 修改巡检任务模板
     */
    @Override
    public Inspection changeInspection(int inspectionId, int inspectionMapId, String inspectionName, int inspectionUserId, int inspectionClassId){
        int rows = inspectionMapper.changeInspection(inspectionId, inspectionMapId, inspectionName, inspectionUserId, inspectionClassId);
        if(rows == 0)
            return null;
        return inspectionMapper.getInspectionById(inspectionId);
    }

    /**
     * 判断巡检任务详情是否存在
     */
    @Override
    public boolean existInspectionData(int inspectionDataId){
        return inspectionDataMapper.getInspectionDataById(inspectionDataId) != null;
    }

    /**
     * 修改任务详情
     */
    @Override
    public InspectionData changeInspectionData(int inspectionDataId, int inspectionId, int inspectionGroupId, int mapDetailId, String inspectionDataDesc, String inspectionDataName){
        int rows = inspectionDataMapper.changeInspectionData(inspectionDataId, inspectionId, inspectionGroupId, mapDetailId, inspectionDataDesc, inspectionDataName);
        if(rows == 0)
            return null;
        return inspectionDataMapper.getInspectionDataById(inspectionDataId);
    }

    /**
     * 删除巡检模板任务
     */
    @Override
    public int deleteInspection(int inspectionId){
        int rows1 = inspectionMapper.deleteInspection(inspectionId);
        int rows2 = inspectionDataMapper.deleteInspection(inspectionId);
        //下面这个将inspectionId改成-1
        int rows3 = inspectionWorkMapper.deleteInspection(inspectionId);
        return rows1;
    }

    /**
     * 判断分配任务是否存在
     */
    @Override
    public boolean existInspectionWork(int inspectionWorkId){
        return inspectionWorkMapper.getInspectionWorkById(inspectionWorkId) != null;
    }

    /**
     * 删除分配巡检任务
     */
    @Override
    public int deleteInspectionWork(int inspectionWorkId){
        int rows1 = inspectionWorkMapper.deleteInspectionWork(inspectionWorkId);
        int rows2 = inspectionDetailMapper.deleteInspectionWork(inspectionWorkId);
        return rows1;
    }

    /**
     * 任务搜索
     */
    @Override
    public List<InspectionVO> searchInspection(int userId, Timestamp startTime, Timestamp endTime, int searchUserId, int mapId){
        List<InspectionVO> inspectionVOList = new ArrayList<>();
        int role = userMapper.getRoleById(userId);
        if(role == 1 || role == 2){
            //管理员可以查看任意用户的任务
            logger.info("查看" + searchUserId + "用户任务");
            return getSearchInspectionVO(startTime, endTime, searchUserId, mapId, role);
        }else {
            //其他用户则只能查看自己的任务
            if(userId != searchUserId) {
                logger.error("不能查看其他人的任务");
                return inspectionVOList;
            }
            return getSearchInspectionVO(startTime, endTime, searchUserId, mapId, role);
        }
    }

    /**
     *通过时间，用户id，地图id查询inspectionVOList
     */
    private List<InspectionVO> getSearchInspectionVO(Timestamp startTime, Timestamp endTime ,int searchUserId, int mapId, int role){
        List<InspectionVO> inspectionVOList = new ArrayList<>();

        Date startDate = new Date(startTime.getTime());
        Date endDate = new Date(endTime.getTime());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.HOUR_OF_DAY, -8);  // 减去 8 个小时
        Date adjustedStartDate = calendar.getTime();  // 获取调整后的时间

        calendar.setTime(endDate);
        calendar.add(Calendar.HOUR_OF_DAY, -8);  // 减去 8 个小时
        Date adjustedEndDate = calendar.getTime();  // 获取调整后的时间

        //这里要分四种情况，searchUserId,mapId都有可能为-1
        if(searchUserId != -1 && mapId != -1) {
            //当用户id和mapId都不为-1时
            List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByUserId(searchUserId);
            List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getInspectionWorkByTime(adjustedStartDate, adjustedEndDate);
            System.out.println(inspectionWorkList);
            //这里要联立查询
            List<InspectionData> inspectionDataList = inspectionDataMapper.getInspectionDataListByMap(mapId);
            for (InspectionDetail inspectionDetail : inspectionDetailList) {
                for (InspectionWork inspectionWork : inspectionWorkList) {
                    //首先确保inspectionWorkId相同
                    if (inspectionDetail.getInspectionWorkId() == inspectionWork.getInspectionWorkId()) {
                        for(InspectionData inspectionData:inspectionDataList){
                            //然后确保inspectionDataId相同
                            if(inspectionDetail.getInspectionDataId() == inspectionData.getInspectionDataId()){
                                //最后确保是同一个任务，inspectionId相同
                                if(inspectionWork.getInspectionId() == inspectionData.getInspectionId()){
                                    //此时就确定了每一组inspection, inspectionWork，inspectionData，inspectionDetail
                                    //此时再判断role是否为3，如果为3，则将inspectionWork的inspectionWorkNumber改为这个user在表中的数量
                                    if(role == 3){
                                        inspectionWork.setInspectionWorkNumber(inspectionDetailMapper.getUserNumber(searchUserId));
                                    }
                                    InspectionVO inspectionVO = new InspectionVO(mapMapper.getMap(mapId), inspectionMapper.getInspectionById(inspectionWork.getInspectionId()), inspectionWork);
                                    inspectionVOList.add(inspectionVO);
                                }
                            }
                        }
                    }
                }
            }
            LinkedHashSet<InspectionVO> hashSet = new LinkedHashSet<>(inspectionVOList);
            List<InspectionVO> list = new ArrayList<>(hashSet);
            return list;
        }else if (searchUserId == -1 && mapId != -1){
            //查询某张地图某天的所有任务
            List<Inspection> inspectionList = inspectionMapper.getInspectionByMap(mapId);
            List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getInspectionWorkByTime(adjustedStartDate, adjustedEndDate);
            for(Inspection inspection:inspectionList){
                for(InspectionWork inspectionWork:inspectionWorkList){
                    if(inspection.getInspectionId() == inspectionWork.getInspectionId()){
                        //此时再判断role是否为3，如果为3，则将inspectionWork的inspectionWorkNumber改为这个user在表中的数量
                        if(role == 3){
                            inspectionWork.setInspectionWorkNumber(inspectionDetailMapper.getUserNumber(searchUserId));
                        }
                        InspectionVO inspectionVO = new InspectionVO(mapMapper.getMap(mapId), inspection, inspectionWork);
                        inspectionVOList.add(inspectionVO);
                    }
                }
            }
            LinkedHashSet<InspectionVO> hashSet = new LinkedHashSet<>(inspectionVOList);
            List<InspectionVO> list = new ArrayList<>(hashSet);
            return list;
        }else if (searchUserId != -1 && mapId == -1){
            //查询某天某人的所有任务
            List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getInspectionWorkByTime(adjustedStartDate, adjustedEndDate);
            List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByUserId(searchUserId);
            for(InspectionWork inspectionWork:inspectionWorkList){
                for(InspectionDetail inspectionDetail:inspectionDetailList){
                    if(inspectionWork.getInspectionWorkId() == inspectionDetail.getInspectionWorkId()){
                        Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
                        //此时再判断role是否为3，如果为3，则将inspectionWork的inspectionWorkNumber改为这个user在表中的数量
                        if(role == 3){
                            inspectionWork.setInspectionWorkNumber(inspectionDetailMapper.getUserNumber(searchUserId));
                        }
                        InspectionVO inspectionVO = new InspectionVO(mapMapper.getMap(inspection.getInspectionMapId()), inspection, inspectionWork);
                        inspectionVOList.add(inspectionVO);
                    }
                }
            }
            LinkedHashSet<InspectionVO> hashSet = new LinkedHashSet<>(inspectionVOList);
            List<InspectionVO> list = new ArrayList<>(hashSet);
            return list;
        }else {
            //查询某天的所有任务
            List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getInspectionWorkByTime(adjustedStartDate, adjustedEndDate);
            for(InspectionWork inspectionWork:inspectionWorkList){
                Inspection inspection = inspectionMapper.getInspectionById(inspectionWork.getInspectionId());
                //此时再判断role是否为3，如果为3，则将inspectionWork的inspectionWorkNumber改为这个user在表中的数量
                if(role == 3){
                    inspectionWork.setInspectionWorkNumber(inspectionDetailMapper.getUserNumber(searchUserId));
                }
                InspectionVO inspectionVO = new InspectionVO(mapMapper.getMap(inspection.getInspectionMapId()), inspection, inspectionWork);
                inspectionVOList.add(inspectionVO);
            }
            LinkedHashSet<InspectionVO> hashSet = new LinkedHashSet<>(inspectionVOList);
            List<InspectionVO> list = new ArrayList<>(hashSet);
            return list;
        }
    }

    /**
     * 查找用户巡查，异常，漏检，不合格数
     */
    public StatusNumVO getStatusNumVO(int userId){
        StatusNumVO statusNumVO = new StatusNumVO();
        //inspectionDetailStatus为0
        int inspectionNum = inspectionDetailMapper.getInspectionNum(userId);
        //inspectionDetailStatus为4
        int exceptionNum = inspectionDetailMapper.getExceptionNum(userId);
        //inspectionDetailStatus为1
        int missNum = inspectionDetailMapper.getMissNum(userId);
        //inspection_detail_ischeat为1
        int failureNum = inspectionDetailMapper.getCheatNum(userId);
        statusNumVO.setInspectionNum(inspectionNum);
        statusNumVO.setExceptionNum(exceptionNum);
        statusNumVO.setMissNum(missNum);
        statusNumVO.setFailureNum(failureNum);
        return statusNumVO;
    }

    /**
     * 定期更新用户巡查，异常，漏检，不合格数缓存，每10分钟更新一次
     **/
    @Override
    @Scheduled(fixedRate = 10 * 60 * 1000)
    public void updateCacheStatusNumVO(){
        //先获取用户id列表
        List<Integer> idList = inspectionDetailMapper.getAllUserId();
        //进行去重
        LinkedHashSet<Integer> hashSet = new LinkedHashSet<>(idList);
        List<Integer> list = new ArrayList<>(hashSet);
        //使用并行流实现异步更新
        list.parallelStream().forEach(userId -> {
            StatusNumVO statusNumVO = getStatusNumVO(userId);
            cacheService.put("userIdStatus:" + userId, statusNumVO, timeOut, timeUnit);
        });
        logger.info("更新用户巡查，异常，漏检，不合格数缓存");
    }

    /**
     * 查找用户本周，本季，本月，本年未巡检数
     */
    @Override
    public NonInspectionVO getNonInspection(int userId){
        if(userMapper.getUserByUserId(userId) == null){
            logger.error("该成员不存在");
            return null;
        }
        NonInspectionVO nonInspectionVO = new NonInspectionVO();
        //本周未巡检
        int weekNonInspection = 0;
        //本月未巡检
        int monthNonInspection = 0;
        //本季未巡检
        int quarterNonInspection = 0;
        //本年未巡检
        int yearNonInspection = 0;

        List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByUserId(userId);
        List<InspectionWork> inspectionWorkList = new ArrayList<>();
        for(InspectionDetail inspectionDetail:inspectionDetailList){
            if(inspectionDetail.getInspectionDetailStatus() == 0 || inspectionDetail.getInspectionDetailStatus() == 1)
                //有未完成任务，看属于哪个inspection_work，然后进行去重
                inspectionWorkList.add(inspectionWorkMapper.getInspectionWorkById(inspectionDetail.getInspectionWorkId()));
        }
        //判断多少个未完成巡检任务的点位
//        //去重
//        LinkedHashSet<InspectionWork> hashSet = new LinkedHashSet<>(inspectionWorkList);
//        List<InspectionWork> list = new ArrayList<>(hashSet);

        //然后检查每个任务的起始时间与今天差了多少天，如差的天数在7天之内则为本周未巡检
        Timestamp timestampToday = new Timestamp(System.currentTimeMillis());
        LocalDate today = timestampToday.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        for(InspectionWork inspectionWork:inspectionWorkList){
            Timestamp startTime = inspectionWork.getInspectionStartTime();
            LocalDate startDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            //计算天数差（小于7天为本周之内）
            long daysDiff = ChronoUnit.DAYS.between(startDate, today);
            if(daysDiff >= 0 && daysDiff <= 7){
                //本月本周本季本年未巡检加一
                weekNonInspection++;
                monthNonInspection++;
                quarterNonInspection++;
                yearNonInspection++;
            } else if (daysDiff > 7 && daysDiff <= 30) {
                //本月本季本年未巡检加一
                monthNonInspection++;
                quarterNonInspection++;
                yearNonInspection++;
            } else if(daysDiff > 30 && daysDiff <= 90){
                //本季本年未巡检加一
                quarterNonInspection++;
                yearNonInspection++;
            } else{
                //本年未巡检加一
                yearNonInspection++;
            }
        }
        //构造返回值
        nonInspectionVO.setWeekNonInspection(weekNonInspection);
        nonInspectionVO.setMonthNonInspection(monthNonInspection);
        nonInspectionVO.setQuarterNonInspection(quarterNonInspection);
        nonInspectionVO.setYearNonInspection(yearNonInspection);
        return nonInspectionVO;
    }

    /**
     * 定期更新用户本周本季本月本年未巡检数缓存（1天）
     */
    @Override
    @Scheduled(fixedRate = 60000*60*24)
    public void updateCacheNonInspection(){
        //先获取用户id列表
        List<Integer> idList = inspectionDetailMapper.getAllUserId();
        //进行去重
        LinkedHashSet<Integer> hashSet = new LinkedHashSet<>(idList);
        List<Integer> list = new ArrayList<>(hashSet);
        //使用并行流实现异步更新
        list.parallelStream().forEach(userId -> {
            NonInspectionVO nonInspectionVO = getNonInspection(userId);
            cacheService.put("userIdNonInspection:" + userId, nonInspectionVO, timeOut, timeUnit);
        });
        logger.info("更新用户本周本季本月本年未巡检数缓存");
    }

    /**
     * 根据创建者or模板名称or负责班组搜索模板
     */
    @Override
    public List<Inspection> searchInspectionTemplate(String inspectionName, Integer inspectionUserId, Integer inspectionClassId){
        return inspectionMapper.searchInspectionTemplate(inspectionName, inspectionUserId, inspectionClassId);
    }

    /**
     * 定时更新分配的巡检任务状态
     */
    @Override
    @Scheduled(fixedRate = 10000)
    public void updateCacheInspectionWorkStatus(){
        List<InspectionWork> finishingInspectionWorkList = getFinishingInspectionWork();
        List<InspectionWork> startInspectionWorkList = getStartInspectionWorkList();

        //未开始（4）和处理中（0）任务分开判断，看是否需要改变状态
        for(InspectionWork inspectionWork: startInspectionWorkList) {
            //未开始任务（4），先判断是否达到开始时间，然后判断是否达到截止时间
            Timestamp now = Timestamp.from(Instant.now());
            Timestamp inspectionStartTime = inspectionWork.getInspectionStartTime();
            if (inspectionStartTime.before(now)) {
                // 已经过了开始时间，接下来判断是否达到截止时间
                // 将 endTime 转换为 Instant
                Instant endInstant = inspectionWork.getInspectionStartTime().toInstant();
                // 使用 Duration 增加小时
                Instant newInstant = endInstant.plus(Duration.ofHours(inspectionWork.getInspectionLimitTime()));
                // 将新的 Instant 转换回 Timestamp
                Timestamp inspectionEndTime = Timestamp.from(newInstant);
                if (inspectionEndTime.after(now)) {
                    //没有到达截止时间，状态变成0处理中
                    inspectionWorkMapper.setStatus(0, inspectionWork.getInspectionWorkId());
                } else {
                    //过了截止时间，此时就要判断这个任务的所有分配任务，如果有分配任务状态为0的则状态变为1，没有则变为2
                    inspectionWorkMapper.setStatus(2, inspectionWork.getInspectionWorkId());
                    List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByWorkId(inspectionWork.getInspectionWorkId());
                    for (InspectionDetail inspectionDetail : inspectionDetailList) {
                        if (inspectionDetail.getInspectionDetailStatus() == 0)
                            inspectionWorkMapper.setStatus(1, inspectionWork.getInspectionWorkId());
                    }
                }
            }
            //还没有开始，状态不用变
        }

        for(InspectionWork inspectionWork1: finishingInspectionWorkList){
            //处理中任务,判断是否达到截止时间
            LocalDateTime finishLocalDateTime = inspectionWork1.getInspectionStartTime().toLocalDateTime().plusHours(inspectionWork1.getInspectionLimitTime());
            Timestamp finishTime = Timestamp.valueOf(finishLocalDateTime);
            if(finishTime.toInstant().isBefore(Instant.now())){
                //已超时，此时就要判断这个任务的所有分配任务，如果有分配任务状态为0的则状态变为1，没有则变为2
                inspectionWorkMapper.setStatus(2, inspectionWork1.getInspectionWorkId());
                List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByWorkId(inspectionWork1.getInspectionWorkId());
                for(InspectionDetail inspectionDetail:inspectionDetailList){
                    if(inspectionDetail.getInspectionDetailStatus() == 0)
                        inspectionWorkMapper.setStatus(1, inspectionWork1.getInspectionWorkId());
                }
            }

        }
    }

    /**
     * 获取处理中任务
     */
    @Override
    public List<InspectionWork> getFinishingInspectionWork(){
        List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getFinishingInspectionWork();
        if(inspectionWorkList.isEmpty() || inspectionWorkList == null){
            return new ArrayList<>();
        }
        return inspectionWorkList;
    }

    /**
     * 获取未完成任务
     */
    @Override
    public List<InspectionWork> getStartInspectionWorkList(){
        List<InspectionWork> inspectionWorkList = inspectionWorkMapper.getStartInspectionWork();
        if(inspectionWorkList.isEmpty() || inspectionWorkList == null){
            return new ArrayList<>();
        }
        return inspectionWorkList;
    }

    /**
     * 提交数据
     */
    @Override
    public int submitInspection(int inspectionDetailId, int inspectionGroupId, List<TextVO> textVOList  , MultipartFile[] images, MultipartFile cheatMsg, boolean isAbnormal) throws IOException {
        List<String> attributeList = inspectionGroupMapper.getAscAttributeByGroupId(inspectionGroupId);
        List<String> valueList = new ArrayList<>();
        String inspectionDataValue = "";

        String inspectionFolder = basePath + "\\" + "inspectionDetailId" + inspectionDetailId;
        String imagesFolder = inspectionFolder + "\\" + "images";
        String cheatMsgFolder = inspectionFolder + "\\" + "cheatMsg";

        int minDb = 40;
        int maxDb = 60;

        //按照attribute对应的inspectionGroupDetailId递增的顺序进行排序，然后对应的得到排序后的valueList
        for(String attribute:attributeList){
            for(TextVO textVO:textVOList){
                if(textVO.getAttribute().equals(attribute))
                    valueList.add(textVO.getValue());
            }
        }

        //组合inspectionDataValue变量
        for (int index = 0; index < valueList.size(); index++) {
            String value = valueList.get(index);
            if (index == 0) {
                inspectionDataValue = value; // 第一个值直接赋值
            } else {
                inspectionDataValue += "/" + value; // 后续值拼接
            }
        }

        //给任务数值进行赋值
        int rows1 = inspectionDetailMapper.setDataValue(inspectionDetailId, inspectionDataValue.toString());

        //设置巡检点位任务完成时间
        Timestamp now = Timestamp.from(Instant.now());
        logger.info("now:" + now);
        inspectionDetailMapper.setEndTime(inspectionDetailId, now);

        //修改巡检点位任务状态
        int inspectionWorkStatus = 2;
        InspectionWork inspectionWork = inspectionWorkMapper.getInspectionWorkById(inspectionDetailMapper.getInspectionWorkIdByDetailId(inspectionDetailId));
        //为避免重复增加，无录音信息时（表示未提交过）才会给完成点位数量加一
        if(inspectionDetailMapper.getCheatMsg(inspectionDetailId) == null || inspectionDetailMapper.getCheatMsg(inspectionDetailId).isEmpty()) {
            int rows5 = inspectionWorkMapper.addNum(inspectionWork.getInspectionWorkId());
        }
        int rows4 = inspectionDetailMapper.setStatus(inspectionDetailId, 2);

        //提交之后判断inspection_work中，对应的这个任务是否全部完成，完成则判断是否有超时，然后修改状态
        if(inspectionWorkMapper.getInspectionWorkNumber(inspectionWork.getInspectionWorkId()) == inspectionWorkMapper.getInspectionWorkFinish(inspectionWork.getInspectionWorkId())){
            //全部完成，先设置完成时间（现在），然后判断是否超过截止时间
            Timestamp endTime = Timestamp.from(Instant.now());
            logger.info("endTime:" + endTime);
            inspectionWorkMapper.setEndTime(endTime, inspectionWork.getInspectionWorkId());

            // 将 endTime 转换为 Instant
            Instant endInstant = inspectionWork.getInspectionStartTime().toInstant();
            // 使用 Duration 增加小时
            Instant newInstant = endInstant.plus(Duration.ofHours(inspectionWork.getInspectionLimitTime()));
            // 将新的 Instant 转换回 Timestamp
            Timestamp finishTime = Timestamp.from(newInstant);
            logger.info("finishTime:" + finishTime);

            //结束时间在截止时间之前，未超时，设为已完成
            inspectionWorkStatus = 2;
            inspectionWorkMapper.setStatus(inspectionWorkStatus, inspectionWork.getInspectionWorkId());
            if(endTime.after(finishTime)) {
                //结束时间在截止时间之后，设为已超时，并将对应的状态为0的巡检点位的状态改为1，已超时
                inspectionWorkStatus = 1;
                inspectionWorkMapper.setStatus(inspectionWorkStatus, inspectionWork.getInspectionWorkId());
                //然后检查所有对应的巡检分配任务，如果有状态为0的，则变为1已超时
                List<InspectionDetail> inspectionDetailList = inspectionDetailMapper.getDetailByWorkId(inspectionWork.getInspectionWorkId());
                for(InspectionDetail inspectionDetail:inspectionDetailList){
                    if(inspectionDetail.getInspectionDetailStatus() == 0){
                        inspectionDetailMapper.setStatus(inspectionDetail.getInspectionDetailId(), 1);
                    }
                }
            }
        }

        if(isAbnormal){
            inspectionDetailMapper.setStatus(inspectionDetailId, 4);
        }

        //检查文件夹是否存在
        File inspectionDir = new File(inspectionFolder);
        if(!inspectionDir.exists()){
            //创建文件夹
            inspectionDir.mkdirs();
            //创建images文件夹和cheatMsg文件夹
            new File(imagesFolder).mkdirs();
            new File(cheatMsgFolder).mkdirs();
        }

        for (MultipartFile image : images) {
            if (image != null && !image.isEmpty()) {
                try {
                    String fileName = image.getOriginalFilename();
                    image.transferTo(new File(imagesFolder + "\\" + fileName));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //将保存图片的文件夹放到数据库中
            int rows2 = inspectionDetailMapper.setImage(inspectionDetailId, imagesFolder);
        }

        if(cheatMsg != null && !cheatMsg.isEmpty()){
        //保存cheatMsg文件夹
        try{
            String fileName = cheatMsg.getOriginalFilename();
            cheatMsg.transferTo(new File(cheatMsgFolder + "\\" + fileName));
        }catch (IOException e){
            e.printStackTrace();
        }
        //将保存cheatMsg的文件夹路径放到数据库中
        int rows3 = inspectionDetailMapper.setCheatMsg(inspectionDetailId, cheatMsgFolder);
        }

        //获取音频文件的绝对路径，对文件夹中每个文件都进行检测，有一个为"Negative"则判0
        Path path = Paths.get(cheatMsgFolder);

        // 使用 Files 类获取文件夹中的所有文件路径
        List<String> filePaths = Files.list(path)
                .filter(Files::isRegularFile) // 过滤出文件
                .map(Path::toAbsolutePath) // 获取文件的绝对路径
                .map(Path::toString)
                .collect(Collectors.toList());

        if(!filePaths.isEmpty() && filePaths != null) {
            inspectionDetailMapper.setIsCheat(0, inspectionDetailId);
            for (String filePath : filePaths) {
                //读取音频文件，判断是否作弊，0为没作弊，1为作弊
                String isCheatMsg = executePythonScript(scriptPath, filePath, minDb, maxDb);
                if (isCheatMsg.equals("Negative"))
                    inspectionDetailMapper.setIsCheat(1, inspectionDetailId);
            }
        }

        return rows1;
    }

    /**
     * 调用python模型，分析音频文件
     */
    @Override
    public String executePythonScript(String scriptPath, String audioFilePath, double minDb, double maxDb) {
        try {
            // 构建Python命令并传递三个参数
            //ProcessBuilder processBuilder = new ProcessBuilder(
              //       "C:\\Users\\<用户名>\\.virtualenvs\\<虚拟环境名>\\Scripts\\activate && python", scriptPath, audioPath, minDb, maxDb);

            ProcessBuilder processBuilder = new ProcessBuilder(pythonInterpreter, scriptPath, audioFilePath, String.valueOf(minDb), String.valueOf(maxDb));

            // 设置工作目录（如果需要）
            // processBuilder.directory(new File("/path/to/your/python/scripts"));

            // 启动进程
            Process process = processBuilder.start();

            // 获取脚本的输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder output = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line);
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                // 匹配 "yamnet" 后面的所有字符
                String pattern = "yamnet(.*)";

                // 使用正则表达式查找匹配的部分
                java.util.regex.Pattern r = java.util.regex.Pattern.compile(pattern);
                java.util.regex.Matcher m = r.matcher(output.toString());

                // 如果匹配成功
                if (m.find()) {
                    // 输出匹配到的部分
                    logger.info("Matched part: " + m.group(1));
                    return m.group(1);
                } else {
                    logger.error("No match found");
                    return null;
                }
            } else {
                BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                StringBuilder errorOutput = new StringBuilder();
                while ((line = errorReader.readLine()) != null) {
                    errorOutput.append(line);
                }
                throw new RuntimeException("Python脚本执行错误：" + errorOutput.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("调用Python脚本时出错", e);
        }
    }
    
    /**
     * 取出保存图像（返回图片存在nginx里面的文件的http路径）
     */
    @Override
    public List<String> getPictures(int inspectionDetailId){
        String inspectionDetailImg = inspectionDetailMapper.getImg(inspectionDetailId);
        //本地图片路径
        List<String> imagePathList = new ArrayList<>();
        //nginx图片的http路径
        List<String> urlPathList = new ArrayList<>();
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(inspectionDetailImg), "*.{jpg,jpeg,png,gif}")) {
            for (Path entry : stream) {
                imagePathList.add(entry.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String baseUrl = "http://106.53.100.120:8070/";
        for(String path:imagePathList){
            String urlPath = path.replace("/home/sujianning/nginx/html/", "");
            urlPath = baseUrl + urlPath;
            urlPathList.add(urlPath);
        }
        return urlPathList;
    }

    private boolean isImageFile(File file) {
        String fileName = file.getName().toLowerCase();
        return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".png") || fileName.endsWith(".gif") || fileName.endsWith(".bmp");
    }

    /**
     * 定时删除分配巡检任务
     * 每天删除30天之前的
     */
    @Override
    @Scheduled(fixedRate = 24 * 60 * 60 * 1000)
    public void deleteInspectionOnTime(){
        //获取所有状态为2已完成并且结束时间在30天之前的分配巡检任务id
        List<Integer> inspectionWorkIdList = inspectionWorkMapper.getMonthFinishedInspectionWork();
        for(Integer inspectionWorkId:inspectionWorkIdList){
            inspectionWorkMapper.deleteInspectionWork(inspectionWorkId);
            inspectionDetailMapper.deleteInspectionWork(inspectionWorkId);
        }
    }

    /**
     * 获取点位数据
     */
    @Override
    public List<DataVO> getDetailData(int inspectionGroupId, int inspectionDetailId){
        List<DataVO> dataVOList = new ArrayList<>();
        List<String> attributeList = inspectionGroupMapper.getAscAttributeByGroupId(inspectionGroupId);
        String valueStr = inspectionDetailMapper.getValueStr(inspectionDetailId);
        List<String> valueList = Arrays.stream(valueStr.split("/"))
                .collect(Collectors.toList());
        for(int index = 0; index < valueList.size(); index++){
            DataVO dataVO = new DataVO(attributeList.get(index), valueList.get(index));
            dataVOList.add(dataVO);
        }
        return dataVOList;
    }

    /**
     * 判断某用户是否有分配巡检任务
     */
    @Override
    public boolean existInspectionDetailUser(int userId){
        return !(inspectionDetailMapper.getDetailByUserId(userId).isEmpty() || inspectionDetailMapper.getDetailByUserId(userId) == null);
    }


    /**
     * 判断用户是否为管理员
     */
    @Override
    public boolean isAdmin(int userId){
        return userMapper.getRoleById(userId) == 1 || userMapper.getRoleById(userId) == 2;
    }

    /**
     * 查看所有用户本周，本季，本月，本年未巡检数之和
     */
    @Override
    public StatusNumVO getAllStatusNumVO(){
        //inspectionDetailStatus为0
        int inspectionNum = inspectionDetailMapper.getAllInspectionNum();
        //inspectionDetailStatus为4
        int exceptionNum = inspectionDetailMapper.getAllExceptionNum();
        //inspectionDetailStatus为1
        int missNum = inspectionDetailMapper.getAllMissNum();
        //inspection_detail_ischeat为1
        int failureNum = inspectionDetailMapper.getAllCheatNum();
        return new StatusNumVO(inspectionNum, exceptionNum, missNum, failureNum);
    }


}
